<?php

namespace common\modules\wechat\models;

use common\behaviors\TimestampBehavior;
use common\components\ActiveRecord;
use Yii;
use yii\db\Expression;
use yii\helpers\ArrayHelper;

/**
 * 粉丝表
 *
 * @property integer $id
 * @property integer $wid
 * @property string  $open_id
 * @property integer $status
 * @property integer $created_at
 * @property integer $updated_at
 * @property MpUser  $user
 * @property Account wechat
 */
class Fans extends ActiveRecord
{

    /**
     * 取消关注
     */
    const STATUS_UNSUBSCRIBED = -1;

    /**
     * 关注状态
     */
    const STATUS_SUBSCRIBED = 0;

    /**
     * @var array 状态
     */
    public static $statuses = [
        self::STATUS_SUBSCRIBED   => '关注',
        self::STATUS_UNSUBSCRIBED => '取消关注',
    ];

    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        $behaviors = parent::behaviors();

        $behaviors[] = [
            'class'              => TimestampBehavior::className(),
            'createdAtAttribute' => 'created_at',
            'updatedAtAttribute' => 'updated_at',
            'value'              => new Expression('NOW()'),
        ];

        return $behaviors;
    }

    /**
     * @inheritdoc
     */
    public static function find()
    {
        return Yii::createObject(FansQuery::className(), [get_called_class()]);
    }

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%wechat_fans}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['wid', 'open_id'], 'required'],
            [['wid', 'status', 'created_at', 'updated_at'], 'integer'],
            [['open_id'], 'string', 'max' => 50],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id'         => 'ID',
            'wid'        => '微信公众号',
            'open_id'    => 'OpenID',
            'status'     => '状态',
            'created_at' => '关注时间',
            'updated_at' => '修改时间',
        ];
    }

    /**
     * 关联公众号
     *
     * @return \yii\db\ActiveQuery
     */
    public function getWechat()
    {
        return $this->hasOne(Account::className(), ['id' => 'wid']);
    }

    /**
     * 关联的用户信息
     *
     * @return \yii\db\ActiveQuery
     */
    public function getUser()
    {
        return $this->hasOne(MpUser::className(), ['id' => 'id']);
    }

    /**
     * 通过唯一的openid查询粉丝
     * openid是跟微信公众号一一关联并唯一的
     *
     * @param $open_id
     * @return mixed
     */
    public static function findByOpenId($open_id)
    {
        return self::findOne(['open_id' => $open_id]);
    }

    /**
     * 更新粉丝为已关注状态
     *
     * @return bool
     */
    public function subscribe()
    {
        $result = $this->updateAttributes(['status' => self::STATUS_SUBSCRIBED]) > 0;
        Yii::info('更新粉丝状态为已关注' . json_encode($this->toArray(), JSON_UNESCAPED_UNICODE), __METHOD__);

        return $result;
    }

    /**
     * 取消关注
     *
     * @return bool
     */
    public function unsubscribe()
    {
        $result = $this->updateAttributes(['status' => self::STATUS_UNSUBSCRIBED]) > 0;
        Yii::info('更新粉丝状态为未关注' . json_encode($this->toArray(), JSON_UNESCAPED_UNICODE), __METHOD__);

        return $result;
    }

    /**
     * 更新用户微信数据
     * 更新失败将会在$this->user->getErrors()中记录错误
     *
     * @param bool $force
     * @return bool
     */
    public function updateUser($force = false)
    {
        $user = $this->user;
        if ( ! $user || $force)
        {
            $wechat = $this->wechat;
            $user = new MpUser();
            $this->populateRelation('user', $user);
            $data = $wechat->getSdk()->getUserInfo($this->open_id);
            if ($data)
            {
                $user->setAttributes([
                    'id'             => $this->id,
                    'nickname'       => ArrayHelper::getValue($data, 'nickname'),
                    'sex'            => ArrayHelper::getValue($data, 'sex'),
                    'city'           => ArrayHelper::getValue($data, 'city'),
                    'country'        => ArrayHelper::getValue($data, 'country'),
                    'province'       => ArrayHelper::getValue($data, 'province'),
                    'language'       => ArrayHelper::getValue($data, 'language'),
                    'avatar'         => ArrayHelper::getValue($data, 'headimgurl'),
                    'subscribe_time' => ArrayHelper::getValue($data, 'subscribe_time'),
                    'remark'         => ArrayHelper::getValue($data, 'remark'),
                    'union_id'       => ArrayHelper::getValue($data, 'unionid', ''), // 测试号无此项
                    'group_id'       => $data['groupid'],
                ]);
                return $user->save();
            }
            $user->addError('id', '用户资料更新失败!');
            return false;
        }
        return true;
    }
}
